// 对于同步日志器和异步日志器性能的测试

// 测试环境：ubutun 20.04 2核4G
// 测试内容：同步下的单线程/多线程   异步下的单线程/多线程
// 测试方法：
// 封装一个接口，传入日志器名称，线程数量，日志数量，单条日志大小
// 在接口内，创建指定数量的线程，各自实现一部分的日志输出
// 同时统计总时间
// 每秒输出量=总的日志条数/总时间
// 每秒输出的日志大小=(总的日志条数*每条日志的大小)/(总时间*1024) 单位是KB

// 测试结果：写100万条日志，每个日志100字节(日志主题消息的大小)
//同步日志器单线程
//线程0:输出数量：1000000,耗时：2.88416s
	// 总耗时: 2.88416s
	// 每秒输出日志数量: 346721条
	// 每秒输出的日志大小: 33859.5KB
//同步日志器多线程
// 线程0:输出数量：333333,耗时：3.98369s
// 线程1:输出数量：333333,耗时：4.31071s
// 线程2:输出数量：333333,耗时：4.40022s
// 	总耗时: 4.40022s
// 	每秒输出日志数量: 227261条
// 	每秒输出的日志大小: 22193.5KB
//异步日志器单线程
// 线程0:输出数量：1000000,耗时：3.35157s
// 	总耗时: 3.35157s
// 	每秒输出日志数量: 298367条
// 	每秒输出的日志大小: 29137.4KB
//异步日志器多线程
// 线程0:输出数量：333333,耗时：3.71485s
// 线程2:输出数量：333333,耗时：3.96434s
// 线程1:输出数量：333333,耗时：4.04507s
// 	总耗时: 4.04507s
// 	每秒输出日志数量: 247215条
// 	每秒输出的日志大小: 24142.1KB




#include "../log/xglog.h"
#include <string>
#include <vector>
#include <thread>
#include <chrono>

void bench(const std::string &logger_name, size_t thr_count, size_t msg_count, size_t msg_len)
{
    // 1,获取对应的日志器
    xglog::logger::ptr Log = xglog::getLogger(logger_name);
    if (Log.get() == nullptr)
    {
        std::cout << logger_name << "日志器不存在" << std::endl;
        return;
    }
    // 2,构建日志消息
    std::string msg = std::string(msg_len - 1, 'A');
    // 3,创建线程
    std::vector<std::thread> threads;
    size_t msg_per_thr = msg_count / thr_count; // 每个线程负责的日志个数
    std::vector<double> cost_array(thr_count);
    for (int i = 0; i < thr_count; i++)
    {
        threads.emplace_back([&, i]()
                             {
            //4,开始计时
            auto start=std::chrono::high_resolution_clock::now();
            //5,进行日志的输出，循环写日志
            for(int j=0;j<msg_per_thr;j++)
            {
                Log->fatal("%s",msg.c_str());
            }
            //6,结束计时
            auto end=std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> cost=end-start;
            cost_array[i]=cost.count();
            std::cout<<"线程"<<i<<":输出数量："<<msg_per_thr<<",耗时："<<cost_array[i]<<"s\n"; });
    }
    for (int i = 0; i < thr_count; i++)
    {
        threads[i].join();
    }
    // 7,计算总耗时
    double max_cost = 0;
    for (int i = 0; i < thr_count; i++)
        max_cost = std::max(max_cost, cost_array[i]);

    std::cout << "\t总耗时: " << max_cost << "s\n";
    std::cout << "\t每秒输出日志数量: " << msg_count / max_cost << "条\n";
    std::cout << "\t每秒输出的日志大小: " << (msg_count * msg_len) / (max_cost * 1024) << "KB\n";
}
// 同步日志器的测试
void sync()
{
    std::unique_ptr<xglog::LoggerBuilder> builder(new xglog::GlobalLoggerBuilder());
    builder->buildLoggerName("SYNC-LOG");                            // 日志器名称
    builder->buildLoggerType(xglog::Logger_Type::LOG_SYNC);          // 同步日志器
    builder->buildLoggerLevel(xglog::LogLevel::value::DEBUG);        // 设置日志最低输出等级
    builder->buildLoggerFormat("[%c][%f:%l]%m%n");                   // 日志输出格式
    builder->buildLoggerSink<xglog::FileSink>("./logfile/sync.log"); // 添加落地方向-指定文件
    builder->build();                                                // 构建日志器

    bench("SYNC-LOG", 3, 1000000, 100);
}
// 异步日志器的测试
void async()
{
    std::unique_ptr<xglog::LoggerBuilder> builder(new xglog::GlobalLoggerBuilder());
    builder->buildLoggerName("ASYNC-LOG");                            // 日志器名称
    builder->buildLoggerType(xglog::Logger_Type::LOG_ASYNC);          // 异步日志器
    builder->buildLoggerLevel(xglog::LogLevel::value::DEBUG);         // 设置日志最低输出等级
    builder->buildAsyncUnsafe();                                      // 开启非安全模式
    builder->buildLoggerFormat("[%c][%f:%l]%m%n");                    // 日志输出格式
    builder->buildLoggerSink<xglog::FileSink>("./logfile/async.log"); // 添加落地方向-指定文件
    builder->build();                                                 // 构建日志器

    bench("ASYNC-LOG", 3, 1000000, 100);
}

int main()
{
    // sync();
    async();
    return 0;
}